// SPDX-FileCopyrightText: 2023-2025 Sangfor Technologies Inc.
// SPDX-License-Identifier: Mulan PSL v2
package com.geniusai.aip.auth.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.geniusai.aip.auth.domain.*;
import com.geniusai.aip.auth.exception.AuthLoginException;
import com.geniusai.aip.auth.exception.AuthLoginExceptionEnum;
import com.geniusai.aip.auth.mapper.UserMapper;
import com.geniusai.aip.auth.utils.CovnerUnitUtils;
import com.geniusai.aip.feature.common.utils.StringUtils;
import com.geniusai.aip.feature.common.utils.executor.TaskExecutorContext;
import com.geniusai.aip.feature.common.web.common.PageModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

import static com.geniusai.aip.auth.constants.AuthCommonConstants.*;

/**
 * @Description
 * @Author: zhangkun91535
 * @Date: 2022-09-20 16:56
 * @Version 1.0
 **/
@Slf4j
@Service
public class RestDataSpaceService {


    @Autowired
    private RestTemplate restTemplate;

    @Value("${spring.datalake-apid.url}")
    private String datalakeApidUrl;

    @Autowired
    private UserMapper userdomapper;


    public void editDataSpaceAsync(EditEntity editEntity) {
        Integer dataSpaceEditFlag = editEntity.getDataSpaceEditFlag();
        if (dataSpaceEditFlag == null || dataSpaceEditFlag == 0 || StringUtils.isBlank(editEntity.getDataSpaceName())) {
            log.info("####dataSpaceEditFlag为[{}],dataSpaceName为[{}],不执行编辑操作####", dataSpaceEditFlag,editEntity.getDataSpaceName());
            return;
        }
        //1新增，2修改，3删除，0 无
        switch (dataSpaceEditFlag) {
            case 1:
                UsersVO usersVO = new UsersVO();
                usersVO.setDataSpaceEditFlag(1);
                usersVO.setDataSpaceName(editEntity.getDataSpaceName());
                usersVO.setDataSpaceCapacity(editEntity.getDataSpaceCapacity());
                usersVO.setDatasetCapacity(editEntity.getDatasetCapacity());
                usersVO.setUsernames(new ArrayList<String>(){{
                    add(editEntity.getUsername());
                }});
                createDataSpaceAsync(usersVO);
                break;
            case 2:
                DataSpaceBO dataSpace = new DataSpaceBO();
                dataSpace.setDataSpaceName(editEntity.getDataSpaceName());
                dataSpace.setDiskCapacity(editEntity.getDataSpaceCapacity());
                dataSpace.setDatasetCapacity(editEntity.getDatasetCapacity());
                editDataSpaceAsyncTruly(dataSpace);
                break;
            case 3:
                deleteDataSpaceAsync(editEntity.getDataSpaceName());
                break;
            default:
                log.warn("not support dataSpaceEditFlag:{}",dataSpaceEditFlag);
        }
    }

    public void editDataSpaceAsyncTruly(DataSpaceBO dataSpace) {
        try {
            log.info("####开始异步编辑数据空间:{}####", dataSpace.getDataSpaceName());
            String cookie = getCookie();
            TaskExecutorContext.getTaskExecutor().submit(() -> {
                try {
                    editDataSpaceTruly(dataSpace,cookie);
                } catch (Exception e) {
                    log.error("####编辑数据空间异常: {}", e.getMessage());
                }
            });
        } catch (Exception e) {
            log.error("####编辑数据空间异常: {}", e.getMessage());
        }

    }

    public void editDataSpaceTruly(DataSpaceBO dataSpace, String cookie) {
        try {
            //添加请求头
            HttpHeaders headers = new HttpHeaders();
            headers.add("Content-Type", "application/json");
            headers.add("Cookie", cookie);
            //3、组装请求头和参数
            HttpEntity<String> formEntity = new HttpEntity<>( headers);
            String dataSpaceUrl = datalakeApidUrl + PUT_DATA_SPACE_CAPACITY_UPDATE_URL
                    .replace("{dataspace}",dataSpace.getDataSpaceName()).replace("{diskcapacity}",
                            dataSpace.getDiskCapacity());
            log.info("user.edit.dataspace.dataspaceCapacity=>dataSpaceUrl [ {} ]",dataSpaceUrl);
            //4、发起post请求
            ResponseEntity<String> dataSpaceCapacity
                    = restTemplate.exchange(dataSpaceUrl, HttpMethod.PUT, formEntity, String.class);
            log.info("user.edit.dataspace.dataspaceCapacity.resp=> [{}]" , dataSpaceCapacity.getBody());

            String datasetUrl = datalakeApidUrl + PUT_DATA_SET_CAPACITY_UPDATE_URL
                    .replace("{dataspace}", dataSpace.getDataSpaceName()).replace("{datasetcapacity}",
                            String.valueOf(dataSpace.getDatasetCapacity()));
            log.info("user.edit.dataspace.datasetCapacity=>datasetUrl [{}]",datasetUrl);

            ResponseEntity<String> datasetCapacity
                    = restTemplate.exchange(datasetUrl,HttpMethod.PUT, formEntity, String.class);
            log.info("user.edit.dataspace.datasetCapacity.resp=> [ {} ]" , datasetCapacity.getBody());

        } catch (Exception e) {
            log.error(e.getMessage(),e);
            throw new AuthLoginException(AuthLoginExceptionEnum.CREATE_DATASPACE_ERROR, "修改数据空间异常: " + e.getMessage());
        }
    }

    /**
     * @Author zhangkun91535
     * @Description 关联数据空间信息
     * @Date 2022/9/19 19:22
     **/
    public void setDataSpaceInfo(PageModel<UserVO> user) {
        List<UserVO> userList = user.getList();
        if (!CollectionUtils.isEmpty(userList)) {
            Set<String> userIds = userList.stream().map(UserVO::getUserId).filter(StringUtils::isNotEmpty).collect(Collectors.toSet());
            List<DataSpace> dataSpaces = userdomapper.selectDataSpaceByNames(userIds);
            if (!CollectionUtils.isEmpty(dataSpaces)) {
                Map<String, DataSpace> userIdDataSpaceMap = new HashMap<>();
                dataSpaces.forEach(dataSpace-> userIdDataSpaceMap.put(dataSpace.getDataSpaceName(),dataSpace));
                userList.forEach(userVO->{
                    //updateTime去掉秒
                    userVO.setUpdateTime(userVO.getUpdateTime() == null ? "-": userVO.getUpdateTime().substring(0,11));
                    DataSpace dataSpace = userIdDataSpaceMap.get(userVO.getUserId());
                    if (dataSpace != null) {
                        userVO.setDatasetCapacity(dataSpace.getDatasetCapacity());
                        userVO.setDatasetUsed(dataSpace.getDatasetUsed());
                        userVO.setUsedCapacity(CovnerUnitUtils.removeZeroDecimal(
                                CovnerUnitUtils.formatSizeWithUnit((long) dataSpace.getDiskUsed(),CovnerUnitUtils.SIZETYPE_GB) ));
                        userVO.setTotalCapacity(CovnerUnitUtils.removeZeroDecimal(
                                CovnerUnitUtils.formatSizeWithUnit((long) dataSpace.getDiskCapacity(),CovnerUnitUtils.SIZETYPE_GB) ));
                        userVO.setDataSpaceName(dataSpace.getDataSpaceName());
                    }else{
                        userVO.setTotalCapacity("0");
                        userVO.setUsedCapacity("0");
                        userVO.setDatasetCapacity(0L);
                        userVO.setDatasetUsed(0L);
                    }
                });
            }else{
                userList.forEach(userVO->{
                    userVO.setTotalCapacity("0");
                    userVO.setUsedCapacity("0");
                    userVO.setDatasetCapacity(0L);
                    userVO.setDatasetUsed(0L);
                });
            }
        }
    }


    /**
     * @Author zhangkun91535
     * @Description 异步创建数据空间
     * @Date 2022/9/16 12:01
     **/
    public void deleteDataSpaceAsync(String dataSpaceName) {
        try {
            if (StringUtils.isBlank(dataSpaceName)) {
                log.info("####dataSpaceName 为[{}],不删除数据空间####", dataSpaceName);
            }
            log.info("####开始异步删除数据空间:{}####", dataSpaceName);
            String cookie = getCookie();
            TaskExecutorContext.getTaskExecutor().submit(() -> {
                try {
                    deleteDataSpace(dataSpaceName,cookie);
                } catch (Exception e) {
                    log.error("####删除数据空间异常: {}", e.getMessage());
                }
            });
        } catch (Exception e) {
            log.error("####删除数据空间异常: {}", e.getMessage());
        }
    }

    /**
     * @Author zhangkun91535
     * @Description 创建数据空间
     * @Date 2022/9/14 17:28
     **/
    public void deleteDataSpace(String dataSpaceName,String cookie) {
        try {
            //1、构建body参数
            //2、添加请求头
            HttpHeaders headers = new HttpHeaders();
            headers.add("Content-Type", "application/json");
            headers.add("Cookie", cookie);
            //3、组装请求头和参数
            HttpEntity<String> formEntity = new HttpEntity<>(headers);
            //4、发起post请求
            ResponseEntity<String> stringResponseEntity;
            stringResponseEntity = restTemplate.exchange(datalakeApidUrl + DELETE_DATA_SPACE_URL + dataSpaceName,
                    HttpMethod.DELETE,formEntity, String.class);
            log.info("user.delete.dataspace.delete.resp=> [ {} ]" , stringResponseEntity.getBody());
        } catch (Exception e) {
            log.error(e.getMessage(),e);
            throw new AuthLoginException(AuthLoginExceptionEnum.CREATE_DATASPACE_ERROR, "删除数据空间异常: " + e.getMessage());
        }

    }

    /**
     * @Author zhangkun91535
     * @Description 异步创建数据空间
     * @Date 2022/9/16 12:01
     **/
    public void createDataSpaceAsync(UsersVO usersVO) {
        try {
            if (usersVO.getDataSpaceEditFlag() == null || usersVO.getDataSpaceEditFlag() == 0 ||
                    org.apache.commons.lang3.StringUtils.isBlank(usersVO.getDataSpaceName())
            ) {
                log.info("####dataSpaceEditFlag 为[{}],dataSpaceName 为[{}],不创建数据空间####", usersVO.getDataSpaceEditFlag(),
                        usersVO.getDataSpaceName());
            }
            log.info("####开始准备异步创建数据空间:{}####", usersVO.getUsernames());
            String cookie = getCookie();
            TaskExecutorContext.getTaskExecutor().submit(() -> {
                try {
                    createDataSpace(usersVO,cookie);
                } catch (Exception e) {
                    log.error("####创建数据空间异常: {}", e.getMessage());
                }
            });
        } catch (Exception e) {
            log.error("####创建数据空间异常: {}", e.getMessage());
        }
    }

    /**
     * @Author zhangkun91535
     * @Description 创建数据空间
     * @Date 2022/9/14 17:28
     **/
    public void createDataSpace(UsersVO usersVO,String cookie) {
        try {
            //1、构建body参数
            String username = usersVO.getUsernames().get(0);
            String dataSpaceName = usersVO.getDataSpaceName();
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("datasetCapacity", usersVO.getDatasetCapacity());
            jsonObject.put("dataspace", dataSpaceName);
            jsonObject.put("diskCapacity", usersVO.getDataSpaceCapacity());
            jsonObject.put("owner", username);
            jsonObject.put("public", false);
            //2、添加请求头
            HttpHeaders headers = new HttpHeaders();
            headers.add("Content-Type", "application/json");
            headers.add("Cookie", cookie);
            //3、组装请求头和参数
            HttpEntity<String> formEntity = new HttpEntity<>(JSON.toJSONString(jsonObject), headers);
            //4、发起post请求
            ResponseEntity<String> stringResponseEntity;
            stringResponseEntity = restTemplate.postForEntity(datalakeApidUrl + POST_CREATE_DATA_SPACE_URL, formEntity, String.class);
            log.info("user.create.dataspace.create.resp=> [ {} ]" , stringResponseEntity.getBody());
        } catch (Exception e) {
            log.error(e.getMessage(),e);
            throw new AuthLoginException(AuthLoginExceptionEnum.CREATE_DATASPACE_ERROR, "创建数据空间异常: " + e.getMessage());
        }

    }

    /**
     * @Author zhangkun91535
     * @Description 获取cookie
     * @Date 2022/9/14 17:44
     **/
    public String getCookie() {
        //获取cookie
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        String cookie = request.getHeader("Cookie");
        if (StringUtils.isEmpty(cookie)) {
            throw new AuthLoginException(AuthLoginExceptionEnum.COOKIE_NEEDED, "Cookie缺失");
        }
        //log.info("data.auth.check=>cookies:{}", cookie);
        return cookie;
    }
}
